﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BOSS.Framework.Search.Result;
using BOSS.Framework.Search.Context;

namespace BOSS.Web.ViewDatas
{
    /// <summary>
    /// 基于集合的搜索结果
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CollectionBasedSearchResult<T> : ISearchResult
    {
        private IEnumerable<T> m_allItems;
        private string m_sortFieldName;
        private bool m_sortDescend;
        private List<object> m_underlayerItems;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="allItems"></param>
        public CollectionBasedSearchResult(string contentType, IEnumerable<T> allItems)
        {
            this.ContentType = contentType;
            this.TotalCount = allItems.Count();
            this.PageSize = 20;
            this.PageIndex = 1;

            this.m_allItems = allItems;
            this.m_sortFieldName = null;
            this.m_sortDescend = false;
            this.m_underlayerItems = null;
        }

        /// <summary>
        /// 设置页大小
        /// </summary>
        /// <param name="pageSize"></param>
        public void SetPageSize(int pageSize)
        {
            int newPageSize = Math.Max(1, pageSize);
            if (this.PageSize != newPageSize)
            {
                this.PageSize = newPageSize;
                this.m_underlayerItems = null;
            }
        }

        /// <summary>
        /// 设置页序号
        /// </summary>
        /// <param name="pageIndex"></param>
        public void SetPageIndex(int pageIndex)
        {
            int newPageIndex = Math.Max(1, pageIndex);
            if (this.PageIndex != newPageIndex)
            {
                this.PageIndex = newPageIndex;
                this.m_underlayerItems = null;
            }
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="descend"></param>
        public void SetSort(string fieldName, bool descend)
        {
            if (!string.IsNullOrEmpty(fieldName)
                && (!fieldName.Equals(this.m_sortFieldName) || (descend != this.m_sortDescend)))
            {
                this.m_sortFieldName = fieldName;
                this.m_sortDescend = descend;
                this.m_underlayerItems = null;
            }
        }

        /// <summary>
        /// 刷新数据
        /// </summary>
        public List<object> Refresh()
        {
            int skip = Math.Min(this.TotalCount, this.PageSize * (this.PageIndex - 1));
            if (skip == this.TotalCount)
            {
                return new List<object>();
            }
            else if (this.TotalCount >= skip + this.PageSize)
            {
                this.PageCount = this.PageSize;
            }
            else
            {
                this.PageCount = this.TotalCount - skip;
            }

            List<object> underlayerItems = new List<object>();

            IEnumerable<T> allItems = this.m_allItems;
            if (!string.IsNullOrEmpty(this.m_sortFieldName))
            {
                if (this.m_sortDescend)
                {
                    allItems = this.m_allItems.OrderByDescending(i => GetPropertyValue(i, this.m_sortFieldName));
                }
                else
                {
                    allItems = this.m_allItems.OrderBy(i => GetPropertyValue(i, this.m_sortFieldName));
                }
            }

            if (this.PageCount > 0)
            {
                int count = 0;
                foreach (var item in allItems)
                {
                    if (skip > 0)
                    {
                        skip--;
                        continue;
                    }
                    underlayerItems.Add(item);
                    count++;
                    if (count == this.PageCount)
                    {
                        break;
                    }
                }
            }

            return underlayerItems;
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        private static object GetPropertyValue(object obj, string propertyName)
        {
            var propertyInfo = obj.GetType().GetProperty(propertyName);
            if (propertyInfo == null)
            {
                return null;
            }
            object value = propertyInfo.GetValue(obj, null);
            if (value == null)
            {
                return null;
            }
            return value.ToString().Trim();
        }

        #region ISearchResult 成员

        /// <summary>
        /// 获取 搜索上下文
        /// </summary>
        public ISearchContext SearchContext
        {
            get { throw new NotSupportedException(); }
        }

        /// <summary>
        /// 获取 内容类型
        /// </summary>
        public string ContentType { get; private set; }

        /// <summary>
        /// 获取 结果总数
        /// </summary>
        public int TotalCount { get; private set; }

        /// <summary>
        /// 获取 分页大小
        /// </summary>
        public int PageSize { get; private set; }

        /// <summary>
        /// 获取 分页的页序号，下标从 1 开始
        /// </summary>
        public int PageIndex { get; private set; }

        /// <summary>
        /// 获取 当前页的条目数
        /// </summary>
        public int PageCount { get; private set; }

        /// <summary>
        /// 获取 当前页的结果条目集合
        /// </summary>
        public IEnumerable<IResultItem> Items
        {
            get { throw new NotSupportedException(); }
        }

        /// <summary>
        /// 获取 当前页的底层结构条目集合
        /// </summary>
        public IEnumerable<object> UnderlayerItems
        {
            get
            {
                if (this.m_underlayerItems == null)
                {
                    this.m_underlayerItems = Refresh();
                }
                return this.m_underlayerItems;
            }
        }

        /// <summary>
        /// 获取 错误信息
        /// </summary>
        public string ErrorMessage
        {
            get { return string.Empty; }
        }

        /// <summary>
        /// 过滤结果条目
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public ISearchResult Filter(Func<object, bool> filter)
        {
            CollectionBasedSearchResult<T> result = new CollectionBasedSearchResult<T>(this.ContentType, this.m_allItems.Where(i => filter(i)));
            result.SetPageSize(this.PageSize);
            result.SetPageIndex(this.PageIndex);
            result.SetSort(this.m_sortFieldName, this.m_sortDescend);
            return result;
        }

        /// <summary>
        /// 过滤结果条目
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public ISearchResult Filter(Func<IResultItem, bool> filter)
        {
            throw new NotSupportedException();
        }

        #endregion
    }
}
